using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;

namespace Microsoft.Cryptography
{
    /// <summary>
    /// Asymmetric signature formatter, which is using the configured RSA-implementation derived from RSABase
    /// </summary>
    public class RSAManagedSignatureFormatter : AsymmetricSignatureFormatter
    {
        private RSABase _rsaKey;
        private string _strOID;

        /// <summary>
        /// Creates a new instance of RSASignatureFormatter 
        /// </summary>
        public RSAManagedSignatureFormatter()
        {
        }

        /// <summary>
        /// Creates a new instance of RSASignatureFormatter with the given AssymetricKey 
        /// </summary>
        /// <param name="key">Asymmetric key, which should be used for signing the XML</param>
        public RSAManagedSignatureFormatter(AsymmetricAlgorithm key)
        {
            SetKey(key);
        }

        /// <summary>
        /// Creates the signature for a calculated hash value
        /// </summary>
        /// <param name="rgbHash">hash value, which should be signed</param>
        /// <returns>byte-array of the signature</returns>
        public override byte[] CreateSignature(byte[] rgbHash)
        {
            if (this._strOID == null)
            {
                throw new Exception(ErrorText.MissingOID);
            }
            if (this._rsaKey == null)
            {
                throw new Exception(ErrorText.MissingKey);
            }
            if (rgbHash == null)
            {
                throw new ArgumentNullException("rgbHash");
            }

            byte[] blob2 = _rsaKey.SignHash(rgbHash, _strOID);

            return blob2;
            
        }

        /// <summary>
        /// Sets the used hash algorithm to the given value
        /// </summary>
        /// <param name="strName">Name of the hash algorithm</param>
        public override void SetHashAlgorithm(string strName)
        {
            _strOID = strName;
        }

        /// <summary>
        /// Sets the asymmetric key, which should be used to sign the message
        /// </summary>
        /// <param name="key">asymmetric key, which should be used to sign the message</param>
        public override void SetKey(AsymmetricAlgorithm key)
        {
            if (key == null)
            {
                throw new ArgumentNullException("key");
            }

            if (!(key is RSA))
            {
                throw new ArgumentException("key must derive from System.Security.Cryptography.RSA");
            }

            object dummy = CryptoConfig.CreateFromName("RSABase");

            if ((dummy == null) || !(dummy is RSABase))
            {
                throw new Exception("The RSA-class configured in machine.config for setting 'RSABase' must derive from Microsoft.Cryptography.RSABase!");
            }
            _rsaKey = (RSABase)dummy;
            _rsaKey.ImportParameters(((RSA)key).ExportParameters(true));


        }
    }
}
